
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_Hans">
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>编写你的第一个 Django 应用，第 3 部分 &#8212; Django 3.2.11.dev 文档</title>
    <link rel="stylesheet" href="../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/language_data.js"></script>
    <link rel="index" title="索引" href="../genindex.html" />
    <link rel="search" title="搜索" href="../search.html" />
    <link rel="next" title="编写你的第一个 Django 应用，第 4 部分" href="tutorial04.html" />
    <link rel="prev" title="编写你的第一个 Django 应用，第 2 部分" href="tutorial02.html" />



 
<script src="../templatebuiltins.js"></script>
<script>
(function($) {
    if (!django_template_builtins) {
       // templatebuiltins.js missing, do nothing.
       return;
    }
    $(document).ready(function() {
        // Hyperlink Django template tags and filters
        var base = "../ref/templates/builtins.html";
        if (base == "#") {
            // Special case for builtins.html itself
            base = "";
        }
        // Tags are keywords, class '.k'
        $("div.highlight\\-html\\+django span.k").each(function(i, elem) {
             var tagname = $(elem).text();
             if ($.inArray(tagname, django_template_builtins.ttags) != -1) {
                 var fragment = tagname.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>");
             }
        });
        // Filters are functions, class '.nf'
        $("div.highlight\\-html\\+django span.nf").each(function(i, elem) {
             var filtername = $(elem).text();
             if ($.inArray(filtername, django_template_builtins.tfilters) != -1) {
                 var fragment = filtername.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>");
             }
        });
    });
})(jQuery);</script>

  </head><body>

    <div class="document">
  <div id="custom-doc" class="yui-t6">
    <div id="hd">
      <h1><a href="../index.html">Django 3.2.11.dev 文档</a></h1>
      <div id="global-nav">
        <a title="Home page" href="../index.html">Home</a>  |
        <a title="Table of contents" href="../contents.html">Table of contents</a>  |
        <a title="Global index" href="../genindex.html">Index</a>  |
        <a title="Module index" href="../py-modindex.html">Modules</a>
      </div>
      <div class="nav">
    &laquo; <a href="tutorial02.html" title="编写你的第一个 Django 应用，第 2 部分">previous</a>
     |
    <a href="index.html" title="开始" accesskey="U">up</a>
   |
    <a href="tutorial04.html" title="编写你的第一个 Django 应用，第 4 部分">next</a> &raquo;</div>
    </div>

    <div id="bd">
      <div id="yui-main">
        <div class="yui-b">
          <div class="yui-g" id="intro-tutorial03">
            
  <div class="section" id="s-writing-your-first-django-app-part-3">
<span id="writing-your-first-django-app-part-3"></span><h1>编写你的第一个 Django 应用，第 3 部分<a class="headerlink" href="#writing-your-first-django-app-part-3" title="永久链接至标题">¶</a></h1>
<p>这一篇从 <a class="reference internal" href="tutorial02.html"><span class="doc">教程第 2 部分</span></a> 结尾的地方继续讲起。我们将继续编写投票应用，并且专注于如何创建公用界面——也被称为“视图”。</p>
<div class="admonition-where-to-get-help admonition">
<p class="first admonition-title">从哪里获得帮助：</p>
<p class="last">如果你在阅读本教程的过程中有任何疑问，可以前往 FAQ 的 <a class="reference internal" href="../faq/help.html"><span class="doc">获取帮助</span></a> 的版块。</p>
</div>
<div class="section" id="s-overview">
<span id="overview"></span><h2>概况<a class="headerlink" href="#overview" title="永久链接至标题">¶</a></h2>
<p>Django 中的视图的概念是「一类具有相同功能和模板的网页的集合」。比如，在一个博客应用中，你可能会创建如下几个视图：</p>
<ul class="simple">
<li>博客首页——展示最近的几项内容。</li>
<li>内容“详情”页——详细展示某项内容。</li>
<li>以年为单位的归档页——展示选中的年份里各个月份创建的内容。</li>
<li>以月为单位的归档页——展示选中的月份里各天创建的内容。</li>
<li>以天为单位的归档页——展示选中天里创建的所有内容。</li>
<li>评论处理器——用于响应为一项内容添加评论的操作。</li>
</ul>
<p>而在我们的投票应用中，我们需要下列几个视图：</p>
<ul class="simple">
<li>问题索引页——展示最近的几个投票问题。</li>
<li>问题详情页——展示某个投票的问题和不带结果的选项列表。</li>
<li>问题结果页——展示某个投票的结果。</li>
<li>投票处理器——用于响应用户为某个问题的特定选项投票的操作。</li>
</ul>
<p>在 Django 中，网页和其他内容都是从视图派生而来。每一个视图表现为一个 Python 函数（或者说方法，如果是在基于类的视图里的话）。Django 将会根据用户请求的 URL 来选择使用哪个视图（更准确的说，是根据 URL 中域名之后的部分）。</p>
<p>在你上网的过程中，很可能看见过像这样美丽的 URL：<code class="docutils literal notranslate"><span class="pre">ME2/Sites/dirmod.htm?sid=&amp;type=gen&amp;mod=Core+Pages&amp;gid=A6CD4967199A42D9B65B1B</span></code>。别担心，Django 里的  <em>URL 样式</em> 要比这优雅的多！</p>
<p>URL 样式是 URL 的一般形式 - 例如：<code class="docutils literal notranslate"><span class="pre">/newsarchive/&lt;year&gt;/&lt;month&gt;/</span></code>。</p>
<p>为了将 URL 和视图关联起来，Django 使用了 'URLconfs' 来配置。URLconf 将 URL 模式映射到视图。</p>
<p>本教程只会介绍 URLconf 的基础内容，你可以看看 <a class="reference internal" href="../topics/http/urls.html"><span class="doc">URL调度器</span></a> 以获取更多内容。</p>
</div>
<div class="section" id="s-writing-more-views">
<span id="writing-more-views"></span><h2>编写更多视图<a class="headerlink" href="#writing-more-views" title="永久链接至标题">¶</a></h2>
<p>现在让我们向 <code class="docutils literal notranslate"><span class="pre">polls/views.py</span></code> 里添加更多视图。这些视图有一些不同，因为他们接收参数：</p>
<div class="literal-block-wrapper docutils container" id="id2">
<div class="code-block-caption"><span class="caption-text">polls/views.py</span><a class="headerlink" href="#id2" title="永久链接至代码">¶</a></div>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">detail</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">question_id</span><span class="p">):</span>
    <span class="k">return</span> <span class="n">HttpResponse</span><span class="p">(</span><span class="s2">&quot;You&#39;re looking at question </span><span class="si">%s</span><span class="s2">.&quot;</span> <span class="o">%</span> <span class="n">question_id</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">results</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">question_id</span><span class="p">):</span>
    <span class="n">response</span> <span class="o">=</span> <span class="s2">&quot;You&#39;re looking at the results of question </span><span class="si">%s</span><span class="s2">.&quot;</span>
    <span class="k">return</span> <span class="n">HttpResponse</span><span class="p">(</span><span class="n">response</span> <span class="o">%</span> <span class="n">question_id</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">vote</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">question_id</span><span class="p">):</span>
    <span class="k">return</span> <span class="n">HttpResponse</span><span class="p">(</span><span class="s2">&quot;You&#39;re voting on question </span><span class="si">%s</span><span class="s2">.&quot;</span> <span class="o">%</span> <span class="n">question_id</span><span class="p">)</span>
</pre></div>
</div>
</div>
<p>把这些新视图添加进 <code class="docutils literal notranslate"><span class="pre">polls.urls</span></code>  模块里，只要添加几个 <a class="reference internal" href="../ref/urls.html#django.conf.urls.url" title="django.conf.urls.url"><code class="xref py py-func docutils literal notranslate"><span class="pre">url()</span></code></a>  函数调用就行：</p>
<div class="literal-block-wrapper docutils container" id="id3">
<div class="code-block-caption"><span class="caption-text">polls/urls.py</span><a class="headerlink" href="#id3" title="永久链接至代码">¶</a></div>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.urls</span> <span class="kn">import</span> <span class="n">path</span>

<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">views</span>

<span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
    <span class="c1"># ex: /polls/</span>
    <span class="n">path</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">index</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">&#39;index&#39;</span><span class="p">),</span>
    <span class="c1"># ex: /polls/5/</span>
    <span class="n">path</span><span class="p">(</span><span class="s1">&#39;&lt;int:question_id&gt;/&#39;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">detail</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">&#39;detail&#39;</span><span class="p">),</span>
    <span class="c1"># ex: /polls/5/results/</span>
    <span class="n">path</span><span class="p">(</span><span class="s1">&#39;&lt;int:question_id&gt;/results/&#39;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">results</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">&#39;results&#39;</span><span class="p">),</span>
    <span class="c1"># ex: /polls/5/vote/</span>
    <span class="n">path</span><span class="p">(</span><span class="s1">&#39;&lt;int:question_id&gt;/vote/&#39;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">vote</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">&#39;vote&#39;</span><span class="p">),</span>
<span class="p">]</span>
</pre></div>
</div>
</div>
<p>然后看看你的浏览器，如果你转到  &quot;/polls/34/&quot; ，Django 将会运行 <code class="docutils literal notranslate"><span class="pre">detail()</span></code> 方法并且展示你在 URL 里提供的问题 ID。再试试 &quot;/polls/34/vote/&quot;  和 &quot;/polls/34/vote/&quot; ——你将会看到暂时用于占位的结果和投票页。</p>
<p>当某人请求你网站的某一页面时——比如说， &quot;/polls/34/&quot; ，Django 将会载入 <code class="docutils literal notranslate"><span class="pre">mysite.urls</span></code> 模块，因为这在配置项 <a class="reference internal" href="../ref/settings.html#std:setting-ROOT_URLCONF"><code class="xref std std-setting docutils literal notranslate"><span class="pre">ROOT_URLCONF</span></code></a> 中设置了。然后 Django 寻找名为 <code class="docutils literal notranslate"><span class="pre">urlpatterns</span></code> 变量并且按序匹配正则表达式。在找到匹配项 <code class="docutils literal notranslate"><span class="pre">'polls/'</span></code>，它切掉了匹配的文本（<code class="docutils literal notranslate"><span class="pre">&quot;polls/&quot;</span></code>），将剩余文本——<code class="docutils literal notranslate"><span class="pre">&quot;34/&quot;</span></code>，发送至 'polls.urls' URLconf 做进一步处理。在这里剩余文本匹配了 <code class="docutils literal notranslate"><span class="pre">'&lt;int:question_id&gt;/'</span></code>，使得我们 Django 以如下形式调用 <code class="docutils literal notranslate"><span class="pre">detail()</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">detail</span><span class="p">(</span><span class="n">request</span><span class="o">=&lt;</span><span class="n">HttpRequest</span> <span class="nb">object</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">question_id</span><span class="o">=</span><span class="mi">34</span><span class="p">)</span>
</pre></div>
</div>
<p>问题 <code class="docutils literal notranslate"><span class="pre">question_id=34</span></code> 来自 <code class="docutils literal notranslate"><span class="pre">&lt;int:question_id&gt;</span></code>。使用尖括号 &quot;获得&quot; 网址部分后发送给视图函数作为一个关键字参数。字符串的 <code class="docutils literal notranslate"><span class="pre">question_id</span></code> 部分定义了要使用的名字，用来识别相匹配的模式，而 <code class="docutils literal notranslate"><span class="pre">int</span></code> 部分是一种转换形式，用来确定应该匹配网址路径的什么模式。冒号 (<code class="docutils literal notranslate"><span class="pre">:</span></code>) 用来分隔转换形式和模式名。</p>
</div>
<div class="section" id="s-write-views-that-actually-do-something">
<span id="write-views-that-actually-do-something"></span><h2>写一个真正有用的视图<a class="headerlink" href="#write-views-that-actually-do-something" title="永久链接至标题">¶</a></h2>
<p>每个视图必须要做的只有两件事：返回一个包含被请求页面内容的 <a class="reference internal" href="../ref/request-response.html#django.http.HttpResponse" title="django.http.HttpResponse"><code class="xref py py-class docutils literal notranslate"><span class="pre">HttpResponse</span></code></a> 对象，或者抛出一个异常，比如 <a class="reference internal" href="../topics/http/views.html#django.http.Http404" title="django.http.Http404"><code class="xref py py-exc docutils literal notranslate"><span class="pre">Http404</span></code></a> 。至于你还想干些什么，随便你。</p>
<p>你的视图可以从数据库里读取记录，可以使用一个模板引擎（比如 Django 自带的，或者其他第三方的），可以生成一个 PDF 文件，可以输出一个 XML，创建一个 ZIP 文件，你可以做任何你想做的事，使用任何你想用的 Python 库。</p>
<p>Django 只要求返回的是一个 <a class="reference internal" href="../ref/request-response.html#django.http.HttpResponse" title="django.http.HttpResponse"><code class="xref py py-class docutils literal notranslate"><span class="pre">HttpResponse</span></code></a> ，或者抛出一个异常。</p>
<p>因为 Django 自带的数据库 API 很方便，我们曾在 <a class="reference internal" href="tutorial02.html"><span class="doc">教程第 2 部分</span></a> 中学过，所以我们试试在视图里使用它。我们在 <code class="docutils literal notranslate"><span class="pre">index()</span></code>  函数里插入了一些新内容，让它能展示数据库里以发布日期排序的最近 5 个投票问题，以空格分割：</p>
<div class="literal-block-wrapper docutils container" id="id4">
<div class="code-block-caption"><span class="caption-text">polls/views.py</span><a class="headerlink" href="#id4" title="永久链接至代码">¶</a></div>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponse</span>

<span class="kn">from</span> <span class="nn">.models</span> <span class="kn">import</span> <span class="n">Question</span>


<span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="n">latest_question_list</span> <span class="o">=</span> <span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;-pub_date&#39;</span><span class="p">)[:</span><span class="mi">5</span><span class="p">]</span>
    <span class="n">output</span> <span class="o">=</span> <span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">q</span><span class="o">.</span><span class="n">question_text</span> <span class="k">for</span> <span class="n">q</span> <span class="ow">in</span> <span class="n">latest_question_list</span><span class="p">])</span>
    <span class="k">return</span> <span class="n">HttpResponse</span><span class="p">(</span><span class="n">output</span><span class="p">)</span>

<span class="c1"># Leave the rest of the views (detail, results, vote) unchanged</span>
</pre></div>
</div>
</div>
<p>这里有个问题：页面的设计写死在视图函数的代码里的。如果你想改变页面的样子，你需要编辑 Python 代码。所以让我们使用 Django 的模板系统，只要创建一个视图，就可以将页面的设计从代码中分离出来。</p>
<p>首先，在你的 <code class="docutils literal notranslate"><span class="pre">polls</span></code> 目录里创建一个 <code class="docutils literal notranslate"><span class="pre">templates</span></code> 目录。Django 将会在这个目录里查找模板文件。</p>
<p>你项目的 <a class="reference internal" href="../ref/settings.html#std:setting-TEMPLATES"><code class="xref std std-setting docutils literal notranslate"><span class="pre">TEMPLATES</span></code></a> 配置项描述了 Django 如何载入和渲染模板。默认的设置文件设置了 <code class="docutils literal notranslate"><span class="pre">DjangoTemplates</span></code> 后端，并将  <a class="reference internal" href="../ref/settings.html#std:setting-TEMPLATES-APP_DIRS"><code class="xref std std-setting docutils literal notranslate"><span class="pre">APP_DIRS</span></code></a>  设置成了 True。这一选项将会让 <code class="docutils literal notranslate"><span class="pre">DjangoTemplates</span></code>  在每个 <a class="reference internal" href="../ref/settings.html#std:setting-INSTALLED_APPS"><code class="xref std std-setting docutils literal notranslate"><span class="pre">INSTALLED_APPS</span></code></a>  文件夹中寻找 &quot;templates&quot; 子目录。这就是为什么尽管我们没有像在第二部分中那样修改 DIRS 设置，Django 也能正确找到 polls 的模板位置的原因。</p>
<p>在你刚刚创建的 <code class="docutils literal notranslate"><span class="pre">templates</span></code> 目录里，再创建一个目录 <code class="docutils literal notranslate"><span class="pre">polls</span></code>，然后在其中新建一个文件 <code class="docutils literal notranslate"><span class="pre">index.html</span></code> 。换句话说，你的模板文件的路径应该是  <code class="docutils literal notranslate"><span class="pre">polls/templates/polls/index.html</span></code> 。因为``app_directories`` 模板加载器是通过上述描述的方法运行的，所以 Django 可以引用到 <code class="docutils literal notranslate"><span class="pre">polls/index.html</span></code>  这一模板了。</p>
<div class="admonition-template-namespacing admonition">
<p class="first admonition-title">模板命名空间</p>
<p class="last">虽然我们现在可以将模板文件直接放在  <code class="docutils literal notranslate"><span class="pre">polls/templates</span></code> 文件夹中（而不是再建立一个 <code class="docutils literal notranslate"><span class="pre">polls</span></code> 子文件夹），但是这样做不太好。Django 将会选择第一个匹配的模板文件，如果你有一个模板文件正好和另一个应用中的某个模板文件重名，Django 没有办法 <em>区分</em> 它们。我们需要帮助 Django 选择正确的模板，最好的方法就是把他们放入各自的 <em>命名空间</em> 中，也就是把这些模板放入一个和 <em>自身</em> 应用重名的子文件夹里。</p>
</div>
<p>将下面的代码输入到刚刚创建的模板文件中：</p>
<div class="literal-block-wrapper docutils container" id="id5">
<div class="code-block-caption"><span class="caption-text">polls/templates/polls/index.html</span><a class="headerlink" href="#id5" title="永久链接至代码">¶</a></div>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">if</span> <span class="nv">latest_question_list</span> <span class="cp">%}</span>
    <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>
    <span class="cp">{%</span> <span class="k">for</span> <span class="nv">question</span> <span class="k">in</span> <span class="nv">latest_question_list</span> <span class="cp">%}</span>
        <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;/polls/</span><span class="cp">{{</span> <span class="nv">question.id</span> <span class="cp">}}</span><span class="s">/&quot;</span><span class="p">&gt;</span><span class="cp">{{</span> <span class="nv">question.question_text</span> <span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
    <span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span>
    <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
<span class="cp">{%</span> <span class="k">else</span> <span class="cp">%}</span>
    <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>No polls are available.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
<span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span>
</pre></div>
</div>
</div>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p class="last">为了让教程看起来不那么长，所有的模板文件都只写出了核心代码。在你自己创建的项目中，你应该使用 <a class="reference external" href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/Getting_started#anatomy_of_an_html_document">完整的 HTML 文档</a> 。</p>
</div>
<p>然后，让我们更新一下 <code class="docutils literal notranslate"><span class="pre">polls/views.py</span></code> 里的 <code class="docutils literal notranslate"><span class="pre">index</span></code> 视图来使用模板：</p>
<div class="literal-block-wrapper docutils container" id="id6">
<div class="code-block-caption"><span class="caption-text">polls/views.py</span><a class="headerlink" href="#id6" title="永久链接至代码">¶</a></div>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponse</span>
<span class="kn">from</span> <span class="nn">django.template</span> <span class="kn">import</span> <span class="n">loader</span>

<span class="kn">from</span> <span class="nn">.models</span> <span class="kn">import</span> <span class="n">Question</span>


<span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="n">latest_question_list</span> <span class="o">=</span> <span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;-pub_date&#39;</span><span class="p">)[:</span><span class="mi">5</span><span class="p">]</span>
    <span class="n">template</span> <span class="o">=</span> <span class="n">loader</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="s1">&#39;polls/index.html&#39;</span><span class="p">)</span>
    <span class="n">context</span> <span class="o">=</span> <span class="p">{</span>
        <span class="s1">&#39;latest_question_list&#39;</span><span class="p">:</span> <span class="n">latest_question_list</span><span class="p">,</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">HttpResponse</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">request</span><span class="p">))</span>
</pre></div>
</div>
</div>
<p>上述代码的作用是，载入 <code class="docutils literal notranslate"><span class="pre">polls/index.html</span></code>  模板文件，并且向它传递一个上下文(context)。这个上下文是一个字典，它将模板内的变量映射为 Python 对象。</p>
<p>用你的浏览器访问 &quot;/polls/&quot; ，你将会看见一个无序列表，列出了我们在  <a class="reference internal" href="tutorial02.html"><span class="doc">教程第 2 部分</span></a> 中添加的 “What's up” 投票问题，链接指向这个投票的详情页。</p>
<div class="section" id="s-a-shortcut-render">
<span id="a-shortcut-render"></span><h3>一个快捷函数： <a class="reference internal" href="../topics/http/shortcuts.html#django.shortcuts.render" title="django.shortcuts.render"><code class="xref py py-func docutils literal notranslate"><span class="pre">render()</span></code></a><a class="headerlink" href="#a-shortcut-render" title="永久链接至标题">¶</a></h3>
<p>「载入模板，填充上下文，再返回由它生成的 <a class="reference internal" href="../ref/request-response.html#django.http.HttpResponse" title="django.http.HttpResponse"><code class="xref py py-class docutils literal notranslate"><span class="pre">HttpResponse</span></code></a>  对象」是一个非常常用的操作流程。于是 Django 提供了一个快捷函数，我们用它来重写  <code class="docutils literal notranslate"><span class="pre">index()</span></code>  视图：</p>
<div class="literal-block-wrapper docutils container" id="id7">
<div class="code-block-caption"><span class="caption-text">polls/views.py</span><a class="headerlink" href="#id7" title="永久链接至代码">¶</a></div>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.shortcuts</span> <span class="kn">import</span> <span class="n">render</span>

<span class="kn">from</span> <span class="nn">.models</span> <span class="kn">import</span> <span class="n">Question</span>


<span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="n">latest_question_list</span> <span class="o">=</span> <span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;-pub_date&#39;</span><span class="p">)[:</span><span class="mi">5</span><span class="p">]</span>
    <span class="n">context</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;latest_question_list&#39;</span><span class="p">:</span> <span class="n">latest_question_list</span><span class="p">}</span>
    <span class="k">return</span> <span class="n">render</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s1">&#39;polls/index.html&#39;</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
</pre></div>
</div>
</div>
<p>注意到，我们不再需要导入 <a class="reference internal" href="../topics/templates.html#module-django.template.loader" title="django.template.loader"><code class="xref py py-mod docutils literal notranslate"><span class="pre">loader</span></code></a>  和 <a class="reference internal" href="../ref/request-response.html#django.http.HttpResponse" title="django.http.HttpResponse"><code class="xref py py-class docutils literal notranslate"><span class="pre">HttpResponse</span></code></a> 。不过如果你还有其他函数（比如说 <code class="docutils literal notranslate"><span class="pre">detail</span></code>, <code class="docutils literal notranslate"><span class="pre">results</span></code>, 和 <code class="docutils literal notranslate"><span class="pre">vote</span></code> ）需要用到它的话，就需要保持  <code class="docutils literal notranslate"><span class="pre">HttpResponse</span></code>   的导入。</p>
<p>The <a class="reference internal" href="../topics/http/shortcuts.html#django.shortcuts.render" title="django.shortcuts.render"><code class="xref py py-func docutils literal notranslate"><span class="pre">render()</span></code></a> function takes the request object as its
first argument, a template name as its second argument and a dictionary as its
optional third argument. It returns an <a class="reference internal" href="../ref/request-response.html#django.http.HttpResponse" title="django.http.HttpResponse"><code class="xref py py-class docutils literal notranslate"><span class="pre">HttpResponse</span></code></a>
object of the given template rendered with the given context.</p>
</div>
</div>
<div class="section" id="s-raising-a-404-error">
<span id="raising-a-404-error"></span><h2>抛出 404 错误<a class="headerlink" href="#raising-a-404-error" title="永久链接至标题">¶</a></h2>
<p>现在，我们来处理投票详情视图——它会显示指定投票的问题标题。下面是这个视图的代码：</p>
<div class="literal-block-wrapper docutils container" id="id8">
<div class="code-block-caption"><span class="caption-text">polls/views.py</span><a class="headerlink" href="#id8" title="永久链接至代码">¶</a></div>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">Http404</span>
<span class="kn">from</span> <span class="nn">django.shortcuts</span> <span class="kn">import</span> <span class="n">render</span>

<span class="kn">from</span> <span class="nn">.models</span> <span class="kn">import</span> <span class="n">Question</span>
<span class="c1"># ...</span>
<span class="k">def</span> <span class="nf">detail</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">question_id</span><span class="p">):</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">question</span> <span class="o">=</span> <span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="n">question_id</span><span class="p">)</span>
    <span class="k">except</span> <span class="n">Question</span><span class="o">.</span><span class="n">DoesNotExist</span><span class="p">:</span>
        <span class="k">raise</span> <span class="n">Http404</span><span class="p">(</span><span class="s2">&quot;Question does not exist&quot;</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">render</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s1">&#39;polls/detail.html&#39;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;question&#39;</span><span class="p">:</span> <span class="n">question</span><span class="p">})</span>
</pre></div>
</div>
</div>
<p>这里有个新原则。如果指定问题 ID 所对应的问题不存在，这个视图就会抛出一个 <a class="reference internal" href="../topics/http/views.html#django.http.Http404" title="django.http.Http404"><code class="xref py py-exc docutils literal notranslate"><span class="pre">Http404</span></code></a> 异常。</p>
<p>我们稍后再讨论你需要在 <code class="docutils literal notranslate"><span class="pre">polls/detail.html</span></code>  里输入什么，但是如果你想试试上面这段代码是否正常工作的话，你可以暂时把下面这段输进去：</p>
<div class="literal-block-wrapper docutils container" id="id9">
<div class="code-block-caption"><span class="caption-text">polls/templates/polls/detail.html</span><a class="headerlink" href="#id9" title="永久链接至代码">¶</a></div>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="cp">{{</span> <span class="nv">question</span> <span class="cp">}}</span>
</pre></div>
</div>
</div>
<p>这样你就能测试了。</p>
<div class="section" id="s-a-shortcut-get-object-or-404">
<span id="a-shortcut-get-object-or-404"></span><h3>一个快捷函数： <a class="reference internal" href="../topics/http/shortcuts.html#django.shortcuts.get_object_or_404" title="django.shortcuts.get_object_or_404"><code class="xref py py-func docutils literal notranslate"><span class="pre">get_object_or_404()</span></code></a><a class="headerlink" href="#a-shortcut-get-object-or-404" title="永久链接至标题">¶</a></h3>
<p>尝试用 <a class="reference internal" href="../ref/models/querysets.html#django.db.models.query.QuerySet.get" title="django.db.models.query.QuerySet.get"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get()</span></code></a>  函数获取一个对象，如果不存在就抛出 <a class="reference internal" href="../topics/http/views.html#django.http.Http404" title="django.http.Http404"><code class="xref py py-exc docutils literal notranslate"><span class="pre">Http404</span></code></a> 错误也是一个普遍的流程。Django 也提供了一个快捷函数，下面是修改后的详情 <code class="docutils literal notranslate"><span class="pre">detail()</span></code> 视图代码：</p>
<div class="literal-block-wrapper docutils container" id="id10">
<div class="code-block-caption"><span class="caption-text">polls/views.py</span><a class="headerlink" href="#id10" title="永久链接至代码">¶</a></div>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.shortcuts</span> <span class="kn">import</span> <span class="n">get_object_or_404</span><span class="p">,</span> <span class="n">render</span>

<span class="kn">from</span> <span class="nn">.models</span> <span class="kn">import</span> <span class="n">Question</span>
<span class="c1"># ...</span>
<span class="k">def</span> <span class="nf">detail</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">question_id</span><span class="p">):</span>
    <span class="n">question</span> <span class="o">=</span> <span class="n">get_object_or_404</span><span class="p">(</span><span class="n">Question</span><span class="p">,</span> <span class="n">pk</span><span class="o">=</span><span class="n">question_id</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">render</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s1">&#39;polls/detail.html&#39;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;question&#39;</span><span class="p">:</span> <span class="n">question</span><span class="p">})</span>
</pre></div>
</div>
</div>
<p>The <a class="reference internal" href="../topics/http/shortcuts.html#django.shortcuts.get_object_or_404" title="django.shortcuts.get_object_or_404"><code class="xref py py-func docutils literal notranslate"><span class="pre">get_object_or_404()</span></code></a> function takes a Django model
as its first argument and an arbitrary number of keyword arguments, which it
passes to the <a class="reference internal" href="../ref/models/querysets.html#django.db.models.query.QuerySet.get" title="django.db.models.query.QuerySet.get"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get()</span></code></a> function of the
model's manager. It raises <a class="reference internal" href="../topics/http/views.html#django.http.Http404" title="django.http.Http404"><code class="xref py py-exc docutils literal notranslate"><span class="pre">Http404</span></code></a> if the object doesn't
exist.</p>
<div class="admonition-philosophy admonition">
<p class="first admonition-title">设计哲学</p>
<p>为什么我们使用辅助函数 <a class="reference internal" href="../topics/http/shortcuts.html#django.shortcuts.get_object_or_404" title="django.shortcuts.get_object_or_404"><code class="xref py py-func docutils literal notranslate"><span class="pre">get_object_or_404()</span></code></a> 而不是自己捕获 <a class="reference internal" href="../ref/exceptions.html#django.core.exceptions.ObjectDoesNotExist" title="django.core.exceptions.ObjectDoesNotExist"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ObjectDoesNotExist</span></code></a> 异常呢？还有，为什么模型 API 不直接抛出 <a class="reference internal" href="../ref/exceptions.html#django.core.exceptions.ObjectDoesNotExist" title="django.core.exceptions.ObjectDoesNotExist"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ObjectDoesNotExist</span></code></a> 而是抛出 <a class="reference internal" href="../topics/http/views.html#django.http.Http404" title="django.http.Http404"><code class="xref py py-exc docutils literal notranslate"><span class="pre">Http404</span></code></a> 呢？</p>
<p class="last">因为这样做会增加模型层和视图层的耦合性。指导 Django 设计的最重要的思想之一就是要保证松散耦合。一些受控的耦合将会被包含在  <a class="reference internal" href="../topics/http/shortcuts.html#module-django.shortcuts" title="django.shortcuts: Convenience shortcuts that span multiple levels of Django's MVC stack."><code class="xref py py-mod docutils literal notranslate"><span class="pre">django.shortcuts</span></code></a> 模块中。</p>
</div>
<p>也有 <a class="reference internal" href="../topics/http/shortcuts.html#django.shortcuts.get_list_or_404" title="django.shortcuts.get_list_or_404"><code class="xref py py-func docutils literal notranslate"><span class="pre">get_list_or_404()</span></code></a> 函数，工作原理和 <a class="reference internal" href="../topics/http/shortcuts.html#django.shortcuts.get_object_or_404" title="django.shortcuts.get_object_or_404"><code class="xref py py-func docutils literal notranslate"><span class="pre">get_object_or_404()</span></code></a> 一样，除了 <a class="reference internal" href="../ref/models/querysets.html#django.db.models.query.QuerySet.get" title="django.db.models.query.QuerySet.get"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get()</span></code></a> 函数被换成了 <a class="reference internal" href="../ref/models/querysets.html#django.db.models.query.QuerySet.filter" title="django.db.models.query.QuerySet.filter"><code class="xref py py-meth docutils literal notranslate"><span class="pre">filter()</span></code></a> 函数。如果列表为空的话会抛出 <a class="reference internal" href="../topics/http/views.html#django.http.Http404" title="django.http.Http404"><code class="xref py py-exc docutils literal notranslate"><span class="pre">Http404</span></code></a> 异常。</p>
</div>
</div>
<div class="section" id="s-use-the-template-system">
<span id="use-the-template-system"></span><h2>使用模板系统<a class="headerlink" href="#use-the-template-system" title="永久链接至标题">¶</a></h2>
<p>回过头去看看我们的 <code class="docutils literal notranslate"><span class="pre">detail()</span></code> 视图。它向模板传递了上下文变量 <code class="docutils literal notranslate"><span class="pre">question</span></code> 。下面是 <code class="docutils literal notranslate"><span class="pre">polls/detail.html</span></code> 模板里正式的代码：</p>
<div class="literal-block-wrapper docutils container" id="id11">
<div class="code-block-caption"><span class="caption-text">polls/templates/polls/detail.html</span><a class="headerlink" href="#id11" title="永久链接至代码">¶</a></div>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span><span class="cp">{{</span> <span class="nv">question.question_text</span> <span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>
<span class="cp">{%</span> <span class="k">for</span> <span class="nv">choice</span> <span class="k">in</span> <span class="nv">question.choice_set.all</span> <span class="cp">%}</span>
    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span><span class="cp">{{</span> <span class="nv">choice.choice_text</span> <span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
<span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span>
<span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
</pre></div>
</div>
</div>
<p>模板系统统一使用点符号来访问变量的属性。在示例 <code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">question.question_text</span> <span class="pre">}}</span></code> 中，首先 Django 尝试对  <code class="docutils literal notranslate"><span class="pre">question</span></code> 对象使用字典查找（也就是使用 obj.get(str) 操作），如果失败了就尝试属性查找（也就是 obj.str 操作），结果是成功了。如果这一操作也失败的话，将会尝试列表查找（也就是 obj[int] 操作）。</p>
<p>在 <a class="reference internal" href="../ref/templates/builtins.html#std:templatetag-for"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">{%</span> <span class="pre">for</span> <span class="pre">%}</span></code></a>  循环中发生的函数调用：<code class="docutils literal notranslate"><span class="pre">question.choice_set.all</span></code> 被解释为 Python 代码 <code class="docutils literal notranslate"><span class="pre">question.choice_set.all()</span></code> ，将会返回一个可迭代的 <code class="docutils literal notranslate"><span class="pre">Choice</span></code> 对象，这一对象可以在 <a class="reference internal" href="../ref/templates/builtins.html#std:templatetag-for"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">{%</span> <span class="pre">for</span> <span class="pre">%}</span></code></a>  标签内部使用。</p>
<p>查看 <a class="reference internal" href="../topics/templates.html"><span class="doc">模板指南</span></a> 可以了解关于模板的更多信息。</p>
</div>
<div class="section" id="s-removing-hardcoded-urls-in-templates">
<span id="removing-hardcoded-urls-in-templates"></span><h2>去除模板中的硬编码 URL<a class="headerlink" href="#removing-hardcoded-urls-in-templates" title="永久链接至标题">¶</a></h2>
<p>还记得吗，我们在 <code class="docutils literal notranslate"><span class="pre">polls/index.html</span></code> 里编写投票链接时，链接是硬编码的：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;/polls/</span><span class="cp">{{</span> <span class="nv">question.id</span> <span class="cp">}}</span><span class="s">/&quot;</span><span class="p">&gt;</span><span class="cp">{{</span> <span class="nv">question.question_text</span> <span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</pre></div>
</div>
<p>问题在于，硬编码和强耦合的链接，对于一个包含很多应用的项目来说，修改起来是十分困难的。然而，因为你在 <code class="docutils literal notranslate"><span class="pre">polls.urls</span></code> 的 <a class="reference internal" href="../ref/urls.html#django.conf.urls.url" title="django.conf.urls.url"><code class="xref py py-func docutils literal notranslate"><span class="pre">url()</span></code></a> 函数中通过 name 参数为 URL 定义了名字，你可以使用  <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">url</span> <span class="pre">%}</span></code> 标签代替它：</p>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;</span><span class="cp">{%</span> <span class="k">url</span> <span class="s1">&#39;detail&#39;</span> <span class="nv">question.id</span> <span class="cp">%}</span><span class="s">&quot;</span><span class="p">&gt;</span><span class="cp">{{</span> <span class="nv">question.question_text</span> <span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</pre></div>
</div>
<p>这个标签的工作方式是在 <code class="docutils literal notranslate"><span class="pre">polls.urls</span></code> 模块的 URL 定义中寻具有指定名字的条目。你可以回忆一下，具有名字 'detail'  的 URL 是在如下语句中定义的：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">...</span>
<span class="c1"># the &#39;name&#39; value as called by the {% url %} template tag</span>
<span class="n">path</span><span class="p">(</span><span class="s1">&#39;&lt;int:question_id&gt;/&#39;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">detail</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">&#39;detail&#39;</span><span class="p">),</span>
<span class="o">...</span>
</pre></div>
</div>
<p>如果你想改变投票详情视图的 URL，比如想改成 <code class="docutils literal notranslate"><span class="pre">polls/specifics/12/</span></code> ，你不用在模板里修改任何东西（包括其它模板），只要在 <code class="docutils literal notranslate"><span class="pre">polls/urls.py</span></code> 里稍微修改一下就行：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">...</span>
<span class="c1"># added the word &#39;specifics&#39;</span>
<span class="n">path</span><span class="p">(</span><span class="s1">&#39;specifics/&lt;int:question_id&gt;/&#39;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">detail</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">&#39;detail&#39;</span><span class="p">),</span>
<span class="o">...</span>
</pre></div>
</div>
</div>
<div class="section" id="s-namespacing-url-names">
<span id="namespacing-url-names"></span><h2>为 URL 名称添加命名空间<a class="headerlink" href="#namespacing-url-names" title="永久链接至标题">¶</a></h2>
<p>教程项目只有一个应用，<code class="docutils literal notranslate"><span class="pre">polls</span></code> 。在一个真实的 Django 项目中，可能会有五个，十个，二十个，甚至更多应用。Django 如何分辨重名的 URL 呢？举个例子，<code class="docutils literal notranslate"><span class="pre">polls</span></code>  应用有 <code class="docutils literal notranslate"><span class="pre">detail</span></code> 视图，可能另一个博客应用也有同名的视图。Django 如何知道 <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">url</span> <span class="pre">%}</span></code> 标签到底对应哪一个应用的 URL 呢？</p>
<p>答案是：在根 URLconf 中添加命名空间。在 <code class="docutils literal notranslate"><span class="pre">polls/urls.py</span></code> 文件中稍作修改，加上 <code class="docutils literal notranslate"><span class="pre">app_name</span></code> 设置命名空间：</p>
<div class="literal-block-wrapper docutils container" id="id12">
<div class="code-block-caption"><span class="caption-text">polls/urls.py</span><a class="headerlink" href="#id12" title="永久链接至代码">¶</a></div>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.urls</span> <span class="kn">import</span> <span class="n">path</span>

<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">views</span>

<span class="n">app_name</span> <span class="o">=</span> <span class="s1">&#39;polls&#39;</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
    <span class="n">path</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">index</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">&#39;index&#39;</span><span class="p">),</span>
    <span class="n">path</span><span class="p">(</span><span class="s1">&#39;&lt;int:question_id&gt;/&#39;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">detail</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">&#39;detail&#39;</span><span class="p">),</span>
    <span class="n">path</span><span class="p">(</span><span class="s1">&#39;&lt;int:question_id&gt;/results/&#39;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">results</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">&#39;results&#39;</span><span class="p">),</span>
    <span class="n">path</span><span class="p">(</span><span class="s1">&#39;&lt;int:question_id&gt;/vote/&#39;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">vote</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">&#39;vote&#39;</span><span class="p">),</span>
<span class="p">]</span>
</pre></div>
</div>
</div>
<p>现在，编辑 <code class="docutils literal notranslate"><span class="pre">polls/index.html</span></code> 文件，从：</p>
<div class="literal-block-wrapper docutils container" id="id13">
<div class="code-block-caption"><span class="caption-text">polls/templates/polls/index.html</span><a class="headerlink" href="#id13" title="永久链接至代码">¶</a></div>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;</span><span class="cp">{%</span> <span class="k">url</span> <span class="s1">&#39;detail&#39;</span> <span class="nv">question.id</span> <span class="cp">%}</span><span class="s">&quot;</span><span class="p">&gt;</span><span class="cp">{{</span> <span class="nv">question.question_text</span> <span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</pre></div>
</div>
</div>
<p>修改为指向具有命名空间的详细视图：</p>
<div class="literal-block-wrapper docutils container" id="id14">
<div class="code-block-caption"><span class="caption-text">polls/templates/polls/index.html</span><a class="headerlink" href="#id14" title="永久链接至代码">¶</a></div>
<div class="highlight-html+django notranslate"><div class="highlight"><pre><span></span><span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;</span><span class="cp">{%</span> <span class="k">url</span> <span class="s1">&#39;polls:detail&#39;</span> <span class="nv">question.id</span> <span class="cp">%}</span><span class="s">&quot;</span><span class="p">&gt;</span><span class="cp">{{</span> <span class="nv">question.question_text</span> <span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</pre></div>
</div>
</div>
<p>当你对你写的视图感到满意后，请阅读 <a class="reference internal" href="tutorial04.html"><span class="doc">教程的第 4 部分</span></a> 了解基础的表单处理和通用视图。</p>
</div>
</div>


          </div>
        </div>
      </div>
      
        
          <div class="yui-b" id="sidebar">
            
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../contents.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">编写你的第一个 Django 应用，第 3 部分</a><ul>
<li><a class="reference internal" href="#overview">概况</a></li>
<li><a class="reference internal" href="#writing-more-views">编写更多视图</a></li>
<li><a class="reference internal" href="#write-views-that-actually-do-something">写一个真正有用的视图</a><ul>
<li><a class="reference internal" href="#a-shortcut-render">一个快捷函数： <code class="docutils literal notranslate"><span class="pre">render()</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#raising-a-404-error">抛出 404 错误</a><ul>
<li><a class="reference internal" href="#a-shortcut-get-object-or-404">一个快捷函数： <code class="docutils literal notranslate"><span class="pre">get_object_or_404()</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#use-the-template-system">使用模板系统</a></li>
<li><a class="reference internal" href="#removing-hardcoded-urls-in-templates">去除模板中的硬编码 URL</a></li>
<li><a class="reference internal" href="#namespacing-url-names">为 URL 名称添加命名空间</a></li>
</ul>
</li>
</ul>

  <h4>上一个主题</h4>
  <p class="topless"><a href="tutorial02.html"
                        title="上一章">编写你的第一个 Django 应用，第 2 部分</a></p>
  <h4>下一个主题</h4>
  <p class="topless"><a href="tutorial04.html"
                        title="下一章">编写你的第一个 Django 应用，第 4 部分</a></p>
  <div role="note" aria-label="source link">
    <h3>本页</h3>
    <ul class="this-page-menu">
      <li><a href="../_sources/intro/tutorial03.txt"
            rel="nofollow">显示源代码</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3>快速搜索</h3>
    <div class="searchformwrapper">
    <form class="search" action="../search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="转向" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    </div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
              <h3>Last update:</h3>
              <p class="topless">12月 07, 2021</p>
          </div>
        
      
    </div>

    <div id="ft">
      <div class="nav">
    &laquo; <a href="tutorial02.html" title="编写你的第一个 Django 应用，第 2 部分">previous</a>
     |
    <a href="index.html" title="开始" accesskey="U">up</a>
   |
    <a href="tutorial04.html" title="编写你的第一个 Django 应用，第 4 部分">next</a> &raquo;</div>
    </div>
  </div>

      <div class="clearer"></div>
    </div>
  </body>
</html>